package socket;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;


public class Server1 {
    private ServerSocket serverSocket;

    //每连接一个客户端，就把该客户端对应的输出流存入集合中
    private List<PrintWriter> allOut = new ArrayList<>();

    public Server1(){
        try {
            serverSocket = new ServerSocket(8089);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void start(){

        try {
            while (true){
                System.out.println("正在等待客户端连接....");
                Socket socket = serverSocket.accept();
                System.out.println("一个客户端已经连接！");
                Runnable r = new ClientHandler(socket);
                Thread t = new Thread(r);
                t.start();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public static void main(String[] args) {
        Server1 server1 = new Server1();
        server1.start();
    }

    private class ClientHandler implements Runnable{
        private Socket socket;
        private String host;

        public ClientHandler(Socket socket){
            this.socket = socket;
            host = socket.getInetAddress().getHostAddress();
        }

        public void run(){
            PrintWriter pw = null;
            try {
                BufferedReader br = new BufferedReader(
                        new InputStreamReader(
                                socket.getInputStream()
                        )
                );
                 pw = new PrintWriter(
                        new BufferedWriter(
                                new OutputStreamWriter(
                                        socket.getOutputStream(),"UTF-8"
                                )
                        ),true
                );
                //每连接一个客户端，就会产生一个输出流，我们把所有输出流放在同一个地方，然后遍历，让每一个输出流写入
                //每一个客户端发送过来的消息，然后每一个客户端再读，就可以实现聊天室的功能
                synchronized (Server1.this) {
                    allOut.add(pw);
                    sendmessage(host+"上线了,当前在线人数："+allOut.size());
                    System.out.println(host+"上线了，当前在线人数:"+allOut.size());
                }
                String message;
                while((message = br.readLine()) != null){
                    System.out.println(host+"说:"+message);
                    sendmessage(host+"说:"+message);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                //当一个客户端断开连接后，把数组缩容，以免其他的线程将消息再次发给该客户端
                synchronized (Server1.this){
                    Iterator<PrintWriter> iterator = allOut.iterator();
                    while (iterator.hasNext()){
                       PrintWriter pw1 =  iterator.next();
                       if (pw1 == pw){
                           iterator.remove();
                       }
                    }
                    sendmessage(host+"下线了,当前在线人数为："+allOut.size());
                    System.out.println(host+"下线了,当前在线人数为："+allOut.size());
                }

            }
        }

        public void sendmessage(String message){
            synchronized(Server1.this){
                for (PrintWriter pw : allOut){
                    pw.println(message);
                }
            }
        }

    }
}
